﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;

namespace Project
{

    class Hook : GameEntity, Renderable
    {
        private GameEntity user;

        private Model model;
        private Effect modelEffect;
        private PointLight light;

        // the hook becomes activated when it hits a wall
        private bool isActivated = false;

        //Maximum distance that hook can shoot
        private const float MAX_DIST = 20f;

        public void kill()
        {
            health = -1;
            
        }

        public Hook(Vector3 position, Quaternion orientation, GameEntity user)
            : base(position, orientation, 10)
        {
            this.user = user;
            // don't smooth out rotation
            slerpConstant = 1.00f;

            // don't bounce at all
            elasticity = 0.0f;

            // ignore gravity
            gravity = new Vector3(0, 0, 0);
            // ignore friction and drag
            frictionConstant = 0;
            dragConstant = 0;

            // set initial velocity
            velocity = Vector3.Transform(Vector3.Backward, orientation) * 50.0f;

            collisionObject = new CollisionObject(
                new AABB(new Vector3(-0.1f, -0.1f, -0.1f), new Vector3(0.1f, 0.1f, 0.1f), position),
                delegate(CollisionData data)
                {
                    // TODO play a sound to indicate a collision
                    if (data.entity == null)
                    {
                        isActivated = true;
                        this.velocity = Vector3.Zero;
                        this.maxSpeed = 0;
                    }
                }, this
            );

            light = new PointLight(position, new Color(1.0f, 1.0f, 0.25f), 0.00f, 0.5f, 0.01f);
        }

        public override void init(GameState gs)
        {
            base.init(gs);
            modelEffect = gs.loadAsset<Effect>("effects\\item");
            model = gs.loadAsset<Model>("models\\teleporter");
            foreach(ModelMesh mesh in model.Meshes) 
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    part.Effect = modelEffect;
                }
            }
            gs.getScene().pointLights.Add(light);
            gs.getScene().renderables.Add(this);
        }

        public override void destroy(GameState gs)
        {
            base.destroy(gs);
            gs.getScene().pointLights.Remove(light);
            gs.getScene().renderables.Remove(this);
        }

        public void render(GameTime gt, Camera camera)
        {
            Matrix worldMatrix = Matrix.CreateFromQuaternion(orientation) * Matrix.CreateTranslation(-position);
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);
            modelEffect.Parameters["World"].SetValue(worldMatrix);
            modelEffect.Parameters["WVP"].SetValue(worldMatrix * camera.view * camera.projection);
            if (!isActivated)
                modelEffect.Parameters["Color"].SetValue(new Vector4(1, 1, 0, 1));
            else
                modelEffect.Parameters["Color"].SetValue(new Vector4(0, 1, 0, 1));
            foreach (ModelMesh mesh in model.Meshes)
            {
                mesh.Draw();
            }
        }

        public override bool update(GameTime gt, GameState gs)
        {
            // destroy the entity when it dies
            if (health <= 0)
            {
                gs.getSoundManager().pauseSound("sounds/grapplinghookpull");
                return false;
            }

            if (isActivated)
            {
                Vector3 force = position - user.position;
                force.Normalize();
                user.applyForce(force * 100f);
                light.color = new Color(0.25f, 1.0f, 0.25f);
                gs.getSoundManager().playSound("sounds/grapplinghookpull", 0.75f, true);
            }

            // update the light position
            light.position = -position;


            return base.update(gt, gs);
        }
    }
}
